#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <asm/uaccess.h>
 
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/workqueue.h>

#define DEVICE_NAME "my_work_queue"
#define DEVICE_MINOR 0
#define DEVICE_MAJOR 120
#define DEVICE_COUNT 1

struct dev_device {
    dev_t devid;
    struct cdev cdev;
    // 添加设备相关的成员变量
    int major;
    int minor;
    struct class *class;
    struct device *device;
};

static int gpio_num = 115 ;
static int gpio_irq_num;  // 存储GPIO3_A7引脚对应的中断号
struct my_work_struct{
    struct work_struct work;
};
static struct my_work_struct my_work;

void work_func(struct work_struct *work){
    // struct my_work_struct *my_work = container_of(work, struct my_work_struct, work);
    // 执行工作队列的任务
    // ...
    msleep(3000);
    // printk(KERN_INFO my_work->work.data);
    printk(KERN_INFO "Work queue task executed!\n");
}

static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
{
    printk(KERN_INFO "GPIO interrupt triggered!\n");
   
    // 初始化工作队列
    if (!work_pending(&my_work.work)) {
        // 初始化工作队列
        INIT_WORK(&my_work.work, work_func);
    }
    schedule_work(&my_work.work);

    return IRQ_RETVAL(IRQ_HANDLED);
}



static int my_dev_mod_init(void) {
    
    int ret;
    
    gpio_irq_num = gpio_to_irq(gpio_num);
    if (gpio_irq_num < 0) {
        printk(KERN_INFO "Failed to get GPIO interrupt number!\n");
        gpio_free(gpio_num);
        return gpio_irq_num;
    }
    printk(KERN_INFO "GPIO interrupt number =  %d\n", gpio_irq_num);

    // 申请中断
    ret = request_irq(gpio_irq_num, gpio_irq_handler, IRQ_TYPE_EDGE_FALLING, "my_gpio_irq", NULL);
    if (ret < 0) {
        printk(KERN_INFO "Failed to request interrupt!\n");
        gpio_free(gpio_num);
        return ret;
    }
    printk(KERN_INFO "Interrupt request successful! ret = %d\n",ret);
    printk(KERN_INFO "GPIO interrupt driver initialized successfully!\n");
    return 0;
 
}

static void my_dev_mod_exit(void) {
    // 释放中断
    gpio_free(gpio_num);
    free_irq(gpio_to_irq(gpio_num),NULL);
    printk(KERN_INFO "Character device driver exited\n");
}

module_init(my_dev_mod_init);
module_exit(my_dev_mod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wlz"); // 添加作者信息
